import { ref, computed, watch, nextTick } from 'vue'
import { v4 } from 'uuid'
import { generateTitle } from '@/api/modules/home.api'
import { throwError, copyToClipboard } from '@/utils/util'
import { useChatStore } from './useChatStore'
import { useUserStore } from '@/store/useUserStore'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { showNotify } from 'vant'
import { AUTH_TOKEN, SHARE_ID } from '@/config/token-const'

const kbList = ref([])
const sessions = ref([])
const curSessionIndex = ref(null)
const curSession = computed(() => sessions.value.find(item => item.id === curSessionIndex.value))
const inputPrompt = ref('')
const chatMsgRef = ref(null)
const { chatStore } = useChatStore()

const removeStatus = ref(false)

// 初始化操作（选中已有会话）
function sessionInit() {
  const store = chatStore()
  if (store.getSessions().length === 0) {
    // 不存在已有会话，新建初始会话
    store.createSession()
  }
  console.log('存在已有会话')
  sessions.value = store.getSessions()
  setCurSessionIndex(sessions.value[0].id)
}

// 对话（知识库）
async function chatApp() {
  try {
    const userStore = useUserStore()
    // 获取当前session的引用（发送sse请求时当前session可能会切换，因此这里需要直接获取触发sse的session引用）
    const session = curSession.value
    session.msgLoading = true
    session.messages.push({
      role: 'user',
      content: inputPrompt.value,
      chatItemId: v4().replaceAll('-', ''),
    })
    // 对ai的回答先进行占位
    session.messages.push({
      role: 'assistant',
      content: '',
      cited: [],
    })
    const shareId = localStorage.getItem(SHARE_ID) || ''
    const url = `/api/v1/qna?shareId=${shareId}`

    const messages = [
      ...session.messages
        .slice(0, -1)
        .slice(-session.history)
        .map(item => {
          return {
            role: item.role,
            content: item.content,
            chatItemId: item.chatItemId,
          }
        }),
    ]
    let authToken = localStorage.getItem(AUTH_TOKEN)
    fetchEventSource(url, {
      method: 'POST',
      headers: {
        Authorization: authToken,
        'Content-Type': 'application/json',
      },
      openWhenHidden: true,
      body: JSON.stringify({
        appId: session.appId,
        chatId: session.id,
        userId: 'user_01',
        messages,
        answerChatItemId: v4().replaceAll('-', ''),
      }),
      //建立连接的回调
      onopen(response) {
        if (response.status === 401) {
          throw new Error('认证无效或者已过期，请重新登录。')
        }
        if (response.status !== 200) {
          throw new Error('Bad response status: ' + response.status)
        }
      },
      //接收一次数据段时回调，因为是流式返回，所以这个回调会被调用多次
      onmessage(ev) {
        session.msgLoading = false
        console.log(ev)
        // console.log(ev.data)
        // 接口返回值里有空字符串的情况
        if (ev.data === '') {
          return
        }
        try {
          const data = JSON.parse(ev.data)
          const messages = session.messages
          const el = messages[messages.length - 1]
          // console.log(el)
          if (data.docs) {
            console.log(data.docs)
            console.log(data.prompt)
            el.cited = data.docs
          } else if (data.answerChatItemId) {
            el.answerChatItemId = data.answerChatItemId
          } else {
            // console.log(data.content)
            el.content += data.content
          }
          scrollToBottom(chatMsgRef.value)
        } catch (error) {
          console.error(error)
        }
      },
      //连接出现异常回调
      onerror(err) {
        session.msgLoading = false
        console.error(err)
        const messages = session.messages
        const el = messages[messages.length - 1]
        el.content = err.message || '网络请求错误'
        throw err
      },
      //正常结束的回调
      async onclose() {
        console.log('close')
        session.msgLoading = false
        try {
          await setSessionTitle(session)
          console.log(sessions.value)
          saveSessions(sessions.value)
        } catch (error) {
          console.error(error)
        }
      },
    })
    inputPrompt.value = ''
  } catch (error) {
    throwError('AppChat.useChat.chatApp', error)
  }
}

// 用于生成会话(对话)标题
async function setSessionTitle(session) {
  try {
    // if (session.title === '新的对话') {
    //   const res = await generateTitle({
    //     messages: [...session.messages],
    //   })
    //   session.title = res
    //   // session.title = '闲聊'
    // }
    session.title =
      session.messages.filter(item => item.role === 'user').reverse()[0].content || '闲聊'
  } catch (error) {
    console.error(error)
  }
}

// 滚动条置底
function scrollToBottom(dom) {
  nextTick(() => {
    dom.scrollTop = dom.scrollHeight
  })
}

// 同步选中session数据到相关变量
function setCurSessionIndex(id) {
  curSessionIndex.value = id
}

// 同步当前session数据到本地存储
function saveSessions(s) {
  const store = chatStore()
  store.saveSessions(s)
}

// 选中会话
function selectSession(id) {
  setCurSessionIndex(id)
}

// 创建会话（同步到sessions变量与本地存储）
function createSession() {
  const store = chatStore()
  const session = store.createSession()
  sessions.value.unshift(session)
  setCurSessionIndex(session.id)
}

// 删除会话
function removeSession(index) {
  // 缓存当前session引用
  const session = curSession.value
  const [el] = sessions.value.splice(index, 1)
  saveSessions(sessions.value)
  // 判断删除的是否为已选中的
  if (el.id === session.id) {
    // 删除后为空，则新建一个
    if (sessions.value.length === 0) {
      createSession()
    } else {
      if (index > sessions.value.length - 1) {
        // 删除尾部元素，则选中前一个
        setCurSessionIndex(sessions.value[sessions.value.length - 1].id)
      } else {
        // 否则选中后一个
        setCurSessionIndex(sessions.value[index].id)
      }
    }
  }
}

// 消息列表长度变动时滚动条置底
function msgChangeScrollToBottom() {
  watch(
    () => curSession.value?.messages.length,
    () => {
      if (!removeStatus.value) {
        scrollToBottom(chatMsgRef.value)
      }
      removeStatus.value = false
    },
    {
      immediate: true,
      flush: 'post',
    },
  )
}

// 移除记录
function removeMsg(index) {
  const session = curSession.value
  const cindex = sessions.value.findIndex(item => item.id === curSessionIndex.value)
  session.messages.splice(index, 1)
  sessions.value[cindex] = session
  saveSessions(sessions.value)
  removeStatus.value = true
}

// 重发问题
function repeatMsg(item, isShare) {
  inputPrompt.value = item.content
  chatApp(isShare)
}

// 复制问题
function copyMsg(item) {
  copyToClipboard(item.content)
    .then(() => {
      showNotify({ type: 'success', message: '复制成功！' })
    })
    .catch(() => {
      showNotify({ type: 'danger', message: '复制失败！' })
    })
}

// 预览
async function chatPreview(prologue = '') {
  try {
    // 获取当前session的引用（发送sse请求时当前session可能会切换，因此这里需要直接获取触发sse的session引用）
    const session = curSession.value
    if (prologue !== '') {
      session.messages = [
        {
          role: 'assistant',
          content: prologue,
        },
      ]
    } else {
      session.messages = []
    }

    inputPrompt.value = ''
    const cindex = sessions.value.findIndex(item => item.id === curSessionIndex.value)
    sessions.value[cindex] = session
    saveSessions(sessions.value)
  } catch (error) {
    throwError('AppChat.useChat.chatPreview', error)
  }
}

export {
  sessions,
  curSession,
  kbList,
  inputPrompt,
  chatMsgRef,
  sessionInit,
  createSession,
  selectSession,
  removeSession,
  saveSessions,
  chatApp,
  msgChangeScrollToBottom,
  copyMsg,
  removeMsg,
  repeatMsg,
  chatPreview,
}
